#include "stdafx.h"
#include "crOperations.h"
#include <system_error>

NS_CR_BEGIN

namespace filesystem
{
	path absolute(const path& p, const path& base)
	{
		path abs_base(base.is_absolute() ? base : absolute(base));
		path p_root_name(p.root_name());
		path base_root_name(abs_base.root_name());
		path p_root_directory(p.root_directory());

		if (p.empty())
			return abs_base;

		if (!p_root_name.empty())  // p.has_root_name()
		{
			if (p_root_directory.empty())  
				return p_root_name / abs_base.root_directory() / abs_base.relative_path() / p.relative_path();
		}

		else if (!p_root_directory.empty())
		{
#if !defined(_WIN32)
			if (base_root_name.empty())
			{
				return p;
			}
#endif
			return base_root_name / p;
		}
		return p;
	}

	namespace detail
	{
		bool possible_large_file_size_support() { return true; }

		path canonical(const path& p, const path& base, _STD error_code* ec)
		{
			path source(p.is_absolute() ? p : absolute(p, base));
			path root(source.root_path());
			path result;
			
			_STD error_code local_ec;
			file_status stat(status(source, local_ec));

			if (stat.type() == file_not_found) 
			{
				if (ec == 0 )
				{
					throw(filesystem_error(
						"crfk::filesystem::canonical", source,
						std::error_code(ENOENT, std::system_category())
					));
				}
				ec->assign(ENOENT, std::system_category());
				return result;
			}
			else if (local_ec)
			{
				if (ec == 0)
				{
					throw(filesystem_error("crfk::filesystem::canonical", source, local_ec));
				}
				*ec = local_ec;
				return result;
			}

			bool scan(true);
			while (scan)
			{
				scan = false;
				result.clear();
			}
		}
	}
}

NS_CR_END